<?php
	/************************************************************************
	*       This file, in addition to all other parts of X7 Chat are        *
	*                   Copyright 2003-2007 by Tim Chamness.                *
	* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
	* Version:          X7 Chat 3.0.0-A2                                    *
	* Release Date:     October 20, 2007                                    *
	* Author:           Tim Chamness                                        *
	* Copyright:        2003-2007 by Tim Chamness                           *
	* Website:          http://www.x7chat.com/                              *
	* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
	* X7 Chat 3 is free software; you can redistribute it and/or modify     *
	* it under the terms of the GNU General Public License as published by  *
	* the Free Software Foundation; either version 3 of the License, or     *
	* (at your option) any later version.                                   *
	*                                                                       *
	* X7 Chat 3 is distributed in the hope that it will be useful, but      *
	* WITHOUT ANY WARRANTY; without even the implied warranty of            *
	* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU     *
	* General Public License for more details.                              *
	*                                                                       *
	* You should have received a copy of the GNU General Public License     *
	* along with this program.  If not, see <http://www.gnu.org/licenses/>. *
	*                                                                       *
	* Additional Terms, compatible with Section 7 of the GNU GPL v3,        *
	* apply to X7 Chat 3 and all X7 Chat 3 files, including this one.       *
	* You should have received a copy of these Additional Terms in the      *
	* file docs/COPYING.ADDITIONAL_TERMS.  If you did not receive a copy    *
	* please visit <http://www.x7chat.com/COPYING.ADDITIONAL_TERMS/>.       *
	************************************************************************/

	/**
	 * This class contains abstract methods used to send messages.
	 */
	class lib_sending {
		const E_NONE =	0;				// No error occurred
		const E_PERM_SYS_MSG = 	1;		// User cannot send system messages
		const E_PERM_GBL_MSG =	2;		// User cannot send global messages
		const E_PERM_MUTED =	3;		// User is muted in this room
		const E_PERM_NOPM =		4;		// User cannot send private messages
		const E_MESSAGE_EMPTY =	5;		// The message had no content
		const E_PERM_RESTRICTED = 6;	// The message was sent, but only to room moderators
		
		/**
		 * Get the error message associated with an error number
		 *
		 * @param int $error_code The error number
		 * @return The error message associated with that error message
		 */
		public function get_error_message($error_code){
			switch($error_code){
				case lib_sending::E_MESSAGE_EMPTY:
					return $GLOBALS['LANG']->lang_messages->cannot_send_empty;
				break;
				case lib_sending::E_PERM_SYS_MSG:
					return $GLOBALS['LANG']->lang_messages->cannot_send_sys_msg;
				break;
				case lib_sending::E_PERM_GBL_MSG:
					return $GLOBALS['LANG']->lang_messages->cannot_send_gbl_msg;
				break;
				case lib_sending::E_PERM_MUTED:
					return $GLOBALS['LANG']->lang_messages->muted;
				break;
				case lib_sending::E_PERM_NOPM:
					return $GLOBALS['LANG']->lang_messages->nopm;
				break;
				case lib_sending::E_PERM_RESTRICTED:
					return $GLOBALS['LANG']->lang_messages->restricted;	
				break;
				default:
					return '';
				break;
			}
		}
		
		/**
		 * Send a message from one entity to another.  A message cannot be empty.
		 *
		 * @param Object $to The lib_room or lib_user to send the message to, or null to send to all rooms
		 * @param lib_user $from The user sending the message or null if the message is from System
		 * @param string $message The message to send
		 * @param boolean $toself If only the JSON code for this message should be generated and returned,
		 * 		but it should not be written to the cache or database set this to true.  If this is set to
		 * 		true then $override_sys_check is assumed to be true as well.
		 * @param boolean $override_sys_check Set to true to force a system message to succeed even if the
		 * 		user does not have permission to send system messages.  This is assumed to be true if $toself
		 * 		is set to true.
		 * @return If $toself is true the JSON array for the message is returned, otherwise an error code is 
		 * 		returned if an error occurred or E_NONE is returned if no error occurred.
		 */
		public function send($to,$from,$message,$toself=false,$override_sys_check=false){
			global $ses, $settings;
			
			// Force message to be a string
			$message = trim(strval($message));
			
			// Make sure this message is not empty
			if(empty($message))
				return lib_sending::E_MESSAGE_EMPTY;
				
			// This is the data that will be passed to the client
			$out_data = array(
				'lastUpdateTime'=>microtime_float(),
				'operation'=>'new_message',
				'data'=>array(
					'uid'=>null,
					'name'=>null,
					'msg'=>$message,
					'time'=>$ses->time,
					'room'=>null,
					'rtype'=>null,
					'styles'=>$settings['default_style'],
					'restricted'=>false,
				)
			);
			
			// Define the type of entity that is sending this message
			if($from === null){
				// This message is a system message
				$puser =& $ses->user;
				$out_data['data']['uid'] = 0;
				$out_data['data']['name'] = '';
				
				// Check permission to send system messages
				// TODO: Make send_sys_message a room level permission
				if(!$toself && !$override_sys_check && !$puser->has_permission('SEND_SYS_MESSAGE'))
					return lib_sending::E_PERM_SYS_MSG;
				
			}else{
				// This message is from a user
				$puser =& $from;
				$out_data['data']['uid'] = $from->data_cache['uid'];
				$out_data['data']['name'] = $ses->user->data_cache['name'];
				$out_data['data']['styles'] = $from->data_cache['settings']['styles'];
			}
			
			// Define the type of entity to which this message is being sent
			if($to === null){
				// This message is a global message
				$out_data['data']['room'] = '';
				$out_data['data']['rtype'] = 1;
				
				// Check permission to send global messages
				if(!$toself && !$puser->has_permission('SEND_GLOBAL_MESSAGE'))
					return lib_sending::E_PERM_GBL_MSG;
				
			}elseif(get_class($to) == 'lib_room'){
				// This message is sent to a room
				$out_data['data']['room'] = $to->data_cache['rid'];
				$out_data['data']['rtype'] = 1;
				
				// Check if the user cannot send messages because they are muted
				// TODO I replaced MUTE_IMMUNITY with GLOBAL_VOICE, not sure why
				if(!$toself && $to->permission_denied($puser,'SEND_REGULAR_MESSAGE') && !$to->has_permission($puser,'GLOBAL_VOICE'))
					return lib_sending::E_PERM_MUTED;
					
				// See if this message is restricted
				if(!$toself)
						$out_data['data']['restricted'] = (!$to->has_permission($puser,'SEND_REGULAR_MESSAGE') && !$puser->has_permission('GLOBAL_VOICE'));
					
			}else{
				// This is a private message
				$out_data['data']['room'] = $to->data_cache['uid'];
				$out_data['data']['rtype'] = 2;
				
				// Check for instant message sending permissions if this is an instant message
				if(!$toself && !$puser->has_permission('SEND_IM_MESSAGE'))
					return lib_sending::E_PERM_NOPM;
					
			}
			
			if($toself){
				$out_data['lastUpdateTime'] = 0;
				return $out_data;
			}else{
				
				if($to === null){
					// TODO: Implement this feature
				}elseif($out_data['data']['rtype'] == 1){
					$GLOBALS['CACHE']->write("messages/{$out_data['data']['room']}",$out_data);
				}elseif($out_data['data']['rtype'] == 2){
					$GLOBALS['CACHE']->write("private_messages/{$out_data['data']['room']}",$out_data);
				}
				
				if($out_data['data']['restricted'])
					return lib_sending::E_PERM_RESTRICTED;
			}
		
			return lib_sending::E_NONE;
		}
	
	}
	
?>